/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_kernel.htm
 *
 * Zhiqim Kernel is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.kernel.json.parser;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.zhiqim.kernel.json.Json;
import org.zhiqim.kernel.json.JsonParser;
import org.zhiqim.kernel.json.Jsons;
import org.zhiqim.kernel.model.maps.HashMapSS;
import org.zhiqim.kernel.model.maps.LinkedMapSS;
import org.zhiqim.kernel.model.maps.MapSV;
import org.zhiqim.kernel.util.Annotations;
import org.zhiqim.kernel.util.Classes;
import org.zhiqim.kernel.util.Validates;

/**
 * 对象适配器，不包括基本类型、数组类型
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
public class ObjectParser implements JsonParser
{
    private Json jsonMain;
    
    public ObjectParser(Json jsonMain)
    {
        this.jsonMain = jsonMain;
    }
    
    @Override
    public String toString(Object obj)
    {
        StringBuilder strb = new StringBuilder("{");
        Class<?> cls = obj.getClass();
        
        List<Field> fieldList = Classes.getFieldListDeep(cls);
        for (Field field : fieldList)
        {
            String name = Annotations.getFieldName(field);
            
            Object value = null;
            try
            {
                if (!field.isAccessible()){
                    field.setAccessible(true);
                }
                
                value = field.get(obj);
            }
            catch (Exception e)
            {
            }
            
            if (value == null)
                continue;//为null不传入
            
            strb.append("\"").append(name).append("\":").append(jsonMain.toString(value)).append(",");
        }
        
        if (strb.length() > 1)
            strb.setLength(strb.length() - 1);
        
        strb.append("}");
        return strb.toString();
    }

    @Override
    public Object toObject(String json, Class<?> cls)
    {
        HashMapSS map = toMap(json);
        
        Object obj = Classes.newInstance(cls);
        if (obj == null)
            return null;
        
        List<Field> fieldList = Classes.getFieldListDeep(cls);
        for (Field field : fieldList)
        {
            String name = Annotations.getFieldName(field);
            String value = map.get(name);
            if (value == null)
                continue;//字段没有值
                
            //JSON转化为对象
            Class<?> type = field.getType();
            Object vo = jsonMain.toObject(value, type, false);
            
            if (Classes.isCollection(type))
            {//如果是集合类,返回的是List<String>，优先读注解
                Class<?> genericsClass = Annotations.getGenericsClass(field);
                if (genericsClass == null)
                {//如果未注解的，则反射机制取
                    genericsClass = Classes.getFieldGenericTypeOne(field);
                }
                
                if (genericsClass != null)
                {
                    @SuppressWarnings("unchecked")
                    Collection<Object> cList = (Collection<Object>)vo;
                    List<String> strList = new ArrayList<String>();
                    for (Object o : cList)
                        strList.add((String)o);
                    cList.clear();
                    
                    for (String str : strList)
                    {
                        Object o = jsonMain.toObject(str, genericsClass, false);
                        cList.add(o);
                    }

                    vo = cList;
                }
            }
            else if (Classes.isMap(type))
            {
                Class<?> genericsClass = Annotations.getGenericsClass(field);
                if (genericsClass == null)
                {//如果未注解的，则反射机制取
                    genericsClass = Classes.getFieldGenericTypeOne(field);
                }
                
                if (genericsClass != null)
                {
                    @SuppressWarnings("unchecked")
                    Map<String, Object> cMap = (Map<String, Object>)vo;
                    LinkedMapSS strMap = new LinkedMapSS();
                    for (Entry<String, Object> entry : cMap.entrySet())
                    {
                        strMap.put(entry.getKey(), String.valueOf(entry.getValue()));
                    }
                    cMap.clear();
                    
                    for (Entry<String, String> entry : strMap.entrySet())
                    {
                        Object v = jsonMain.toObject(entry.getValue(), genericsClass, false);
                        cMap.put(entry.getKey(), v);
                    }

                    vo = cMap;
                }
            }
            else if (Classes.isMapSV(type))
            {
                Class<?> genericsClass = Annotations.getGenericsClass(field);
                if (genericsClass == null)
                {//如果未注解的，则反射机制取
                    genericsClass = Classes.getFieldGenericTypeOne(field);
                }
                
                if (genericsClass != null)
                {
                    @SuppressWarnings("unchecked")
                    MapSV<Object> cMap = (MapSV<Object>)vo;
                    LinkedMapSS strMap = new LinkedMapSS();
                    for (Entry<String, ?> entry : cMap.entrySet())
                    {
                        strMap.put(entry.getKey(), String.valueOf(entry.getValue()));
                    }
                    cMap.clear();
                    
                    for (Entry<String, String> entry : strMap.entrySet())
                    {
                        Object v = jsonMain.toObject(entry.getValue(), genericsClass, false);
                        cMap.put(entry.getKey(), v);
                    }

                    vo = cMap;
                }
            }
            
            Classes.setFieldValue(obj, field, vo);
        }
        
        return obj;
    }
    
    /** 把对象解析成KEY/VALUE成对的表 */
    private HashMapSS toMap(String json)
    {
        if (Validates.isEmpty(json))
            return new HashMapSS(0);
        
        HashMapSS map = new HashMapSS();
        
        //先把对象分折成每个字段和字段对应的值，注意值有可能是一个对象或数组，即{}或[]成对出现
        List<String> list = Jsons.toListByObject(json);
        for (String s : list)
        {
            int ind = s.indexOf(":");
          
            //注:KEY要去掉两边的引号,VALUE不去掉左右的双单引号，由BaseParser处理
            String key = Jsons.removeStartEndQuotation(s.substring(0, ind));
            String value = s.substring(ind+1);
            
            if ("null".equals(value))
                map.put(key, null);
            else
                map.put(key, value);
        }
        
        return map;
    }
}
